package com.songlanyun.common.kqUtils;

import java.math.BigDecimal;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.net.ssl.SSLContext;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import org.apache.poi.hpsf.Decimal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class InitOrder {
	public static Log logger = LogFactory.getLog(InitOrder.class);

	public static QuickPayProperties quickPayProperties;
	private static final String txnType = "ODR";   //交易类型   固定
	private static final String appScheme = "billdemo";   //支付宝支付填写参数
	private static final String appName = "惠选中亿";   //APP名称

	@Autowired
	public InitOrder(QuickPayProperties properties) {
		quickPayProperties = properties;
	}

	/**
	 * gateWay下单demo
	 * amount 支付金额
     * orderCode 订单编号  APP内唯一
     * payType 支付类型   W2微信   A2支付宝
     * goodsDetails 商品详情
	 * @return
	 */
	public static String gateWayInitOrder(BigDecimal amount , String orderCode , String payType , String goodsDetails)
	{
		Map<String, Object> request = new HashMap<String, Object>();

//		String externalTraceNo = "JH" + new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
		//会员编号
		request.put("memberCode", quickPayProperties.getMemberCode());
		//商户编号
		request.put("merchantId", quickPayProperties.getMerchantId());
		//商户对应的终端编号
		request.put("terminalId", quickPayProperties.getTerminalCode());
		//交易类型:ODR
		request.put("txnType", txnType);	//ODR-下单	RFD-退货
		//交易金额(元)
		request.put("amt", amount);
		//商户订单号
		request.put("externalTraceNo", orderCode);
		//请求时间		格式为:yyyyMMddHHmmss
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		request.put("requestTime", sdf.format(new Date()));
		//支付方式 W2-微信       A2-支付宝    Y-云闪付    Y1-ApplePay 
		request.put("payType", payType);
		//产品信息(商户自己的)
//		request.put("productDesc", "1");
		//结算日期 格式:yyyyMMdd
		SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd");
		request.put("stlDate", ymd.format(new Date()));

		//交易币别(默认人民币CNY)
		request.put("cur", "CNY");
		//请求方IP地址
//		request.put("clientIp", "127.0.0.1");
		request.put("bgUrl", quickPayProperties.getCallBackUrl());
		
		//分账参数:sharingFlag、feeMode、feePayer、sharingData
//		request.put("sharingFlag","1");    //分账标识，固定值1，代表分账
//		request.put("feeMode","0");        //手续费收取方式 ,0:主收款方方式 
//		request.put("feePayer","HAT_10012932671");   //手续费主收款方会员编号,feeMode=0 时需传此项，如果不传默认 memberCode值
//		request.put("sharingData","2^HAT_10012932671^0.01^1^test1|2^HAT_10012934672^0.01^1^test2"); //分账数据
		
		Sign sign = new Sign();
		sign.init(quickPayProperties);
		sign.createPrivateKey();
		String s = sign.doSign(request);
		request.put("sign", s);
		sign.createPublicKey();
		Map<String,String> dataMap=new HashMap<String, String>();
		if("W2".equals(payType)){
			//商户appId 注:当为微信APP支付和公众号支付时必传,值为商户在微信的APPID
			dataMap.put("merchant_appid", quickPayProperties.getMerchantAppid());
		}else{
			dataMap.put("appScheme", appScheme);//当paytype为A2时必传
		}
		//商品描述  注:当为微信APP支付和公众号支付时必传,值为具体的商品详情   APP名+商品名称
		dataMap.put("orderdetail", appName + goodsDetails);
//		dataMap.put("WL.Ipaddress", "127.0.0.1");
		dataMap.put("limit_pay", "1");
		request.put("dataMap", dataMap);
		//订单支付有效时间，单位为秒。如果不传 的话，将默认是 120 秒，值千万不能小 于 60，否则将出现异常 
//		request.put("qrCodeValidTime", "3000"); 
		System.out.println("请求参数:" + JSON.toJSONString(request));
		
		//提交地址
//		String reqUrl ="https://sandbox.99bill.com/sdk-gateway/sdkGatewayService";
		String reqUrl = "https://picsdk.99bill.com/sdk-gateway/sdkGatewayService"; //生产地址


		
		String response = "";
		
		try {

			response = HttpUtil.doPostJsonRequest(JSON.toJSONString(request), reqUrl, 3000, 8000);
			
			//JDK1.8  用LinkedHashMap，两个方法二选一
			//方法一
			Map<String, Object> m = JSON.parseObject(response, LinkedHashMap.class, Feature.OrderedField);
			//方法二
			//Map<String,Object> m = new HashMap<String, Object>();
			//m = JSON.parseObject(response, LinkedHashMap.class, Feature.OrderedField);
			
			//JDK1.8  如果用该方法，验签的mpayInfo顺序错误，会导致验签失败
			//Map<String,Object> m = new HashMap<String, Object>();
			//m = JSON.parseObject(response, Map.class);

//			System.out.println("m==="+m);
			System.out.println("response==="+response);
			sign.verificate(m.get("sign").toString(), m);
			return response;
			
			
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}
	/**
	 * HTTP请求POST方式
	 * 
	 * @param requestObject
	 * @param url
	 * @param connectTimeout
	 * @param socketTimeOut
	 * @return
	 * @throws Exception
	 */
	public static String postHttpRequest(Object requestObject, String url, int connectTimeout, int socketTimeOut)
			throws Exception {
		CloseableHttpResponse response = null;
		try {
			String reqeustString = "{}";
			if (requestObject != null) {
				reqeustString = JSON.toJSONString(requestObject);
			}
			logger.info("[send to gateWay service] message : " + reqeustString);

			CloseableHttpClient httpclient = HttpClients.createDefault();
			
			HttpPost httpPost = new HttpPost(url);
			SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
		    sslContext.init(null, null, null);
		    SSLContext.setDefault(sslContext);	
			
			StringEntity sEntity = new StringEntity(reqeustString, "UTF-8");
			sEntity.setContentType("application/json");
			// 
			RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(connectTimeout)
					.setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeOut).build();
			httpPost.setConfig(requestConfig);
			httpPost.setEntity(sEntity);
			response = httpclient.execute(httpPost);
			// get http status code
			int resStatu = response.getStatusLine().getStatusCode();
			String responseString = null;
			if (resStatu == HttpStatus.SC_OK) {
				responseString = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
			} else {
				logger.error("rquestUrl:" + url + ", the connection is error,statusCode=" + resStatu);
				throw new Exception(url + ",the statusCode is " + resStatu);
			}
			return responseString;
		} catch (ConnectTimeoutException e) {
			logger.error("http post connection timeout", e);
			throw e;
		} catch (SocketTimeoutException e) {
			logger.error("http post socket timeout", e);
			throw e;
		} catch (Exception e) {
			logger.error("http post throw Exception", e);
			throw e;
		} finally {
			if (response != null) {
				try {
					EntityUtils.consume(response.getEntity());
					response.close();
				} catch (Exception e) {
					logger.error("http connection closed error", e);
				}
			}
		}
	}
	
}
